package com.vcc.boss.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.vcc.channel.base.model.request.CreateShareAccountRequest;
import com.vcc.channel.base.service.ChannelBaseService;
import com.vcc.core.annotations.RepeatSubmit;
import com.vcc.core.annotations.RestPack;
import com.vcc.core.exception.NotFoundException;
import com.vcc.core.exception.ProgramException;
import com.vcc.data.entity.*;
import com.vcc.service.boss.share.account.response.BossShareAccountResponse;
import com.vcc.service.boss.share.config.request.BossShareAccountConfigUpdateRequest;
import com.vcc.service.boss.share.config.response.BossShareAccountConfigResponse;
import com.vcc.service.boss.share.order.request.BossShareAccountOrderAuditRequest;
import com.vcc.service.boss.share.order.response.BossShareAccountOrderResponse;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.*;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

@RestController
@RequestMapping("shareAccount")
public class ShareAccountController {


    @Resource
    private ShareAccountOrderService shareAccountOrderService;
    @Resource
    private UserService userService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private ChannelService channelService;
    @Resource
    private CardTypeService cardTypeService;
    @Resource
    private ShareAccountService shareAccountService;
    @Resource
    private ShareAccountConfigService shareAccountConfigService;

    @RestPack
    @SaCheckLogin
    @GetMapping("orderPaging")
    @SaCheckPermission("card:share:order:view")
    public Page<BossShareAccountOrderResponse> orderPaging(
            Integer pageNumber,
            Integer pageSize,
            String orderId,
            Long targetUserId,
            Integer status
    ) {
        if (targetUserId != null && targetUserId != 0L) {
            User user = userService.getById(targetUserId);
            if (!BossUserUtil.hasAllData() && !user.getBeLongToDealer().equals(BossUserUtil.getId())) {
                throw new ProgramException("无权处理该用户的参数配置");
            }

        }
        return shareAccountOrderService.paging(
                pageNumber,
                pageSize,
                orderId,
                targetUserId,
                status
        );
    }


    @RestPack
    @SaCheckLogin
    @PostMapping("auditOrder")
    @SaCheckPermission("card:share:order:audit")
    @RepeatSubmit
    public Boolean auditOrder(@RequestBody @Validated BossShareAccountOrderAuditRequest request) {
        ShareAccountOrder shareAccountOrder = shareAccountOrderService.getByIdOpt(request.getId()).orElseThrow(() -> new ProgramException("申请订单不存在"));
        User user = userService.getById(shareAccountOrder.getUserId());
        if (!BossUserUtil.hasAllData() && !user.getBeLongToDealer().equals(BossUserUtil.getId())) {
            throw new ProgramException("无权处理该用户的参数配置");
        }
        if (request.getStatus() == 0) {
            if (StringUtils.isBlank(request.getName())) {
                throw new ProgramException("通过时请填写账户名称");
            }

            Channel channel = channelService.getByCode(request.getChannelCode());
            if (!channel.getHasShareAccount()) {
                throw new ProgramException("该渠道未开启共享账户功能");
            }
            List<CardType> cardTypeList = cardTypeService.listByChannelNameAndType(channel.getCode(), "share");
            ChannelBaseService channelBaseService = applicationContext.getBean(channel.getCode(), ChannelBaseService.class);
            String channelAccountId = channelBaseService.createShareAccount(
                    CreateShareAccountRequest.builder()
                            .accountName(shareAccountOrder.getOrderId())
                            .channelCode(channel.getCode())
                            .build()
            );
            if (channelAccountId == null || channelAccountId.isEmpty()) {
                throw new ProgramException("创建共享账户失败");
            }
            ShareAccount shareAccount = new ShareAccount();
            shareAccount.setAccountId(channelAccountId);
            shareAccount.setAccountName(request.getName());
            shareAccount.setOrderId(shareAccountOrder.getOrderId());
            shareAccount.setUserId(shareAccountOrder.getUserId());
            shareAccount.setChannelCode(channel.getCode());
            shareAccountService.save(shareAccount);
            List<ShareAccountConfig> list = cardTypeList.stream().map(it -> {
                ShareAccountConfig shareAccountConfig = ShareAccountConfig.builder()
                        .shareAccountId(shareAccount.getId())
                        .userId(shareAccount.getUserId())
                        .cardTypeId(it.getId())
                        .status(0)
                        .amount(BigDecimal.valueOf(-1))
                        .verifyOpenCardStatus(it.getVerifyOpenCardStatus())
                        .verifyUpdateLimitStatus(it.getVerifyRechargeCardStatus())
                        .verifyCloseCardStatus(it.getVerifyCloseCardStatus())
                        .verifyFreezeUnFreezeCardStatus(it.getVerifyCloseCardStatus())
                        .authFee(it.getAuthFee())
                        .authFeeRate(it.getAuthFeeRate())
                        .minAuthFee(it.getMinAuthFee())
                        .minAuthFeeRate(it.getMinAuthFeeRate())
                        .failFee(it.getFailFee())
                        .failFeeRate(it.getFailFeeRate())
                        .refundFee(it.getRefundFee())
                        .refundFeeRate(it.getRefundFeeRate())
                        .reversalFee(it.getReversalFee())
                        .reversalFeeRate(it.getReversalFeeRate())
                        .crossBorderFee(it.getCrossBorderFee())
                        .crossBorderFeeRate(it.getCrossBorderFeeRate())
                        .build();
                return shareAccountConfig;
            }).toList();
            shareAccountConfigService.saveBatch(list);
        } else {
            if (request.getRemark() == null || request.getRemark().isEmpty()) {
                throw new ProgramException("拒绝时请填写拒绝理由");
            }
        }
        return shareAccountOrderService.audit(
                request.getId(),
                request.getStatus(),
                request.getRemark()
        );
    }


    @RestPack
    @SaCheckLogin
    @GetMapping("accountPaging")
    @SaCheckPermission("card:share:account:view")
    public Page<BossShareAccountResponse> accountPaging(
            Integer pageNumber,
            Integer pageSize,
            Long targetUserId,
            String name
    ) {
        if (targetUserId != null && targetUserId != 0L) {
            User user = userService.getById(targetUserId);
            if (!BossUserUtil.hasAllData() && !user.getBeLongToDealer().equals(BossUserUtil.getId())) {
                throw new ProgramException("无权处理该用户的参数配置");
            }

        }
        return shareAccountService.paging(
                pageNumber,
                pageSize,
                targetUserId,
                name,
                null
        ).map(it -> {
            ChannelBaseService channelBaseService = applicationContext.getBean(it.getChannelCode(), ChannelBaseService.class);

            BigDecimal balance = channelBaseService.queryAccountBalance(it.getAccountId());
            it.setBalance(balance);
            it.setAccountId("");
            it.setChannelCode(StpUtil.hasPermission("channel:view") ? it.getChannelCode() : "");
            return it;
        });
    }


    @RestPack
    @SaCheckLogin
    @GetMapping("listConfigByUserId")
    @SaCheckPermission("client:user:share:config:view")
    public List<BossShareAccountConfigResponse> listConfigByUserId(
            Long targetUserId
    ) {
        if (targetUserId != null && targetUserId != 0L) {
            User user = userService.getById(targetUserId);
            if (!BossUserUtil.hasAllData() && !user.getBeLongToDealer().equals(BossUserUtil.getId())) {
                throw new ProgramException("无权处理该用户的参数配置");
            }
        }
        return shareAccountConfigService.listByUserId(targetUserId);
    }

    @RestPack
    @SaCheckLogin
    @PostMapping("shareAccountConfigUpdate")
    @SaCheckPermission("client:user:share:config:edit")
    public Boolean shareAccountConfigUpdate(
            @RequestBody @Validated BossShareAccountConfigUpdateRequest request
    ) {
        ShareAccountConfig shareAccountConfig = shareAccountConfigService.getByIdOpt(request.getId()).orElseThrow(() -> new NotFoundException("用户共享账户参数配置不存在"));
        User user = userService.getById(shareAccountConfig.getUserId());
        if (!BossUserUtil.hasAllData() && !user.getBeLongToDealer().equals(BossUserUtil.getId())) {
            throw new ProgramException("无权处理该用户的参数配置");
        }

        return shareAccountConfigService.update(request);
    }
}
